#pragma once
#include "util/noncopyable.h"

namespace net_tools::util
{
  class Memorypool;
}
namespace net_tools::base
{
  class Base_buffer : public util::noncopyable
  {
  public:
    Base_buffer(int block_number);
    ~Base_buffer();
    static void Singleton_pool(int mempool_block_size, int mempool_block_number);

    void Read_append(int append_byte)
    {
      read_index_ += append_byte;
    };
    void Write_append(int append_byte)
    {
      write_index_ += append_byte;
    };

    void Write(void *buf, unsigned int size);

    Base_buffer *Get_next()
    {
      return next_;
    };
    Base_buffer *Get_pre()
    {
      return before_;
    };
    unsigned int Get_read_residue()
    {
      return write_index_ - read_index_;
    };
    unsigned int Get_write_residue()
    {
      return buf_size_ - write_index_;
    };
    void Clear_index()
    {
      read_index_ = 0;
      write_index_ = 0;
    };
    // write_index == buf_size
    bool Is_full()
    {
      return write_index_ == buf_size_;
    };
    // write_index == read_index
    bool Is_empty()
    {
      return write_index_ == read_index_;
    };

    // self -> other => self -> next -> other
    void Insert_next(Base_buffer *next);
    // other -> self => other -> pre -> self
    void Insert_pre(Base_buffer *pre);

    unsigned int Get_write_index()
    {
      return write_index_;
    };
    unsigned int Get_buf_size()
    {
      return buf_size_;
    };

    char *Write_index(int index = 0)
    {
      return reinterpret_cast<char *>(buf_) + write_index_ + index;
    };
    // only for read,dont change index
    char *operator[](unsigned int index);

  private:
    void *buf_;
    unsigned int write_index_;
    unsigned int read_index_;
    volatile bool free_;
    unsigned int buf_size_;
    Base_buffer *next_;
    Base_buffer *before_;
    static util::Memorypool *mempool_;

  } __attribute__((aligned(64)));

} // net_tools::base